package com.ddxz.demo.shiro.jwt.configuration;

import com.ddxz.demo.shiro.jwt.mapper.ShiroMapper;
import com.ddxz.tool.core.common.DdxzJwtUtil;
import com.ddxz.tool.core.convert.CollectionUtil;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationException;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.Permission;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;

import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * class description
 *
 * @author 朱宗刚
 * @version 1.0.0
 * @date 2020/11/25
 */

public class DdxzRealm extends AuthorizingRealm {
    @Override
    public boolean supports(AuthenticationToken token) {
        return token instanceof DdxzToken;
    }

    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        if(principals == null || principals.isEmpty()) {
            throw new AuthorizationException("PrincipalCollection method argument cannot be null.");
        }

        String token = (String) principals.getPrimaryPrincipal();
        String user = jwtUtil.getBody(token).get("username").toString();
        List<String> roles = mapper.getRoleByUserId(user);
        Set<Permission> permissions = new HashSet<>();
        if(!CollectionUtil.isEmpty(roles)) {
            mapper.getPermissionByRoleId(roles).forEach(per -> permissions.add(new DdxzPermission(per)));
        }
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        info.setObjectPermissions(permissions);
        return info;
    }

    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        AuthenticationInfo info = new SimpleAuthenticationInfo(token.getPrincipal(), token.getCredentials(), name);
        return info;
    }

    private static final String name = "DDXZ_REALM";

    private static final DdxzJwtUtil jwtUtil = new DdxzJwtUtil();

    private ShiroMapper mapper;

    public DdxzRealm(ShiroMapper mapper) {
        this.mapper = mapper;
    }
}
